/* -------------------------------------- 

     Cherrypy webapp skeleton frontend

     License: LGPL
     Authors: saaj (mail@saaj.me)

   -------------------------------------- */

/**
 * Data binding RPC-based data store 
 */
qx.Class.define("webapp.network.RpcStore", {

  extend : qx.data.store.Json,

  construct : function(serviceName, delegate)
  {
  	this.base(arguments, qx.core.Environment.get("webapp.serviceUrl"), delegate);

  	this._createRequest(serviceName);
  },

  events : {

    loading : "qx.event.type.Event"

  },

  members : {

  	_rpc              : null,
  	_lastCall         : null,
  	_isRequestRunning : false,


    // override
    _applyUrl: function(value, old)
    {
    	// do not do implicit load data on url change
    },

    // override
    _createRequest: function(serviceName)
    {
      this._rpc = new webapp.network.Rpc(serviceName);

      this._rpc.addListener("completed", this._loaded, this);
      this._rpc.addListener("failed", this._failed, this);

      if(this._delegate && qx.lang.Type.isFunction(this._delegate.configureRequest))
      {
        this._delegate.configureRequest(this._rpc);
      }
    },

    _failed : function()
    {
      this._isRequestRunning = false;
      this.setState("failed");
    },

    _loaded: function(response)
    {
      var data = response.getData().result;
      this._isRequestRunning = false;

      if(data === undefined)
      {
        return this.setState("failed");
      }

      if(this._delegate && qx.lang.Type.isFunction(this._delegate.manipulateData))
      {
        data = this._delegate.manipulateData(data);
      }

      this._marshaler.toClass(data);
      this.setModel(this._marshaler.toModel(data));

      this.fireDataEvent("loaded", this.getModel());
    },

    load : function(method, params)
    {
    	if(this._isRequestRunning)
    	{
    		return;
    	}

    	this.fireEvent("loading");

      this._lastCall = [method, params];

      this._isRequestRunning = true;
      this._rpc.call(method, params);
    },

    // override
    reload : function()
    {
    	if(!this._lastCall)
    	{
    		throw new Error("reload() must be called only after load()");
    	}

    	this.load.apply(this, this._lastCall);
    }

  }
});